/*
 ******************************************************************************
 *
 *       Copyright ASTRI, 2016.  All rights reserved.
 *
 *   This software is proprietary to and embodies the confidential technology
 *   of Hong Kong Applied Science and Technology Research Institute Company
 *   Limited (ASTRI).
 *   Possession, use, or copying of this software and media is authorized
 *   only pursuant to a valid written license from ASTRI or an authorized
 *   sublicensor.
 *
 * File Name:
 *   XXX.java
 *
 * Purpose:
 *   
 *   
 *   
 *
 * Project or Modules Name:
 *   
 *
 * Modules Contained:
 *   N/A
 *
 * Modification History:
 * Date(DDMMYY)  Version No Modified By  Description
 * ------------  ---------- -----------  -----------
 * 20160405       0.0.0.1    XXX     Created
 *
 ******************************************************************************
 */


package com.j.thetabk.thetas;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by user on 14/4/2016.
 */
public class ThetaSConnectorE extends ThetaSConnectorD {


    public ThetaSNumberA [] numbers=null;

    public static void AddNumberName(JSONArray jainout, int [] indexes)
    {
        for (int indexe : indexes) jainout.put(ThetaSNumber.numberName[indexe]);
    }

    public static void AddNumberNameSupport(JSONArray jainout, int [] indexes)
    {
        for (int indexe : indexes) jainout.put(ThetaSNumber.numberName[indexe] + support);
    }

    public ThetaSConnectorE(String cameraIpAddress) {
        super(cameraIpAddress);
        numbers=new ThetaSNumberA[3];
        for(int i=0;i<3;i++)
            numbers[i]=new ThetaSNumberA();
    }

    public boolean AcquireNumber(int []idx) throws IOException, JSONException {

        JSONArray jaProperties=new JSONArray();
        AddNumberName(jaProperties, idx);
        JSONObject input=AcquirePropertyParam(jaProperties, sessionId);
        JSONObject output = TransmitA(3, input);
        if(IsStateDone(output)) {

            JSONObject jb1=GetProperties(output);

            for (int anIdx : idx) {
                numbers[anIdx].ParseNumber(anIdx,jb1);
            }

            return true;
        }
        return false;
    }

    public boolean SetNumber(int index) throws JSONException, IOException {
        JSONObject input=SetPropertyParam(numbers[index].NumberItem(index), sessionId);
        JSONObject output = TransmitA(3, input);
        if(IsStateDone(output))
        {
            return true;
        }
        return false;
    }

    public boolean UpdateNumber(int []idx) throws IOException, JSONException {
        JSONArray jaProperties=new JSONArray();
        AddNumberName(jaProperties, idx);
        AddNumberNameSupport(jaProperties, idx);
        JSONObject input=AcquirePropertyParam(jaProperties, sessionId);
        JSONObject output = TransmitA(3, input);
        if(IsStateDone(output)) {
            JSONObject jb1=GetProperties(output);
            for (int anIdx : idx) {
                numbers[anIdx].ParseRange(anIdx, jb1.getJSONObject(ThetaSNumber.numberName[anIdx] + support));
                numbers[anIdx].ParseNumber(anIdx, jb1);
            }
            return true;
        }
        return false;
    }

    public String [] TakePhotos(ThetaSBKEventListener listener, int BKIndex, int sleepms) throws IOException, JSONException, InterruptedException {

        String []outNames=new String[numbers[2].value];
        int i=0;
        outNames[i]=_latestFileUri;
        StartVideo();
        do {
            GetState();
            if(!_latestFileUri.equals(outNames[i]))
            {
                outNames[i]=_latestFileUri;
                GetValue();
                listener.onObjectChanged(i,BKIndex);
                i++;
                outNames[i]=_latestFileUri;
            }
            Thread.sleep(sleepms);
        }while(!_captureStatus.equals("idle"));

        GetState();
        while(_latestFileUri.equals(outNames[i]))
        {
            Thread.sleep(sleepms);
            GetState();
        }
        outNames[i]=_latestFileUri;
        GetValue();
        listener.onObjectChanged(i, BKIndex);
        return outNames;
    }

    public String [] TakePhotosWithDelay(ThetaSBKEventListener listener, int BKIndex, int sleepms) throws IOException, JSONException, InterruptedException {

        String []outNames=new String[numbers[2].value];
        int i=0;
        outNames[i]=_latestFileUri;
        StartVideo();

        SelfTimerCountDown(properties[12].choice,listener);

        do {
            GetState();
            if(!_latestFileUri.equals(outNames[i]))
            {
                outNames[i]=_latestFileUri;
                GetValue();
                listener.onObjectChanged(i,BKIndex);
                i++;
                outNames[i]=_latestFileUri;
            }
            Thread.sleep(sleepms);
        }while(!_captureStatus.equals("idle"));

        GetState();
        while(_latestFileUri.equals(outNames[i]))
        {
            Thread.sleep(sleepms);
            GetState();
        }
        outNames[i]=_latestFileUri;
        GetValue();
        listener.onObjectChanged(i, BKIndex);
        return outNames;
    }


    public boolean Sync() throws IOException, JSONException {
        GetInfo();
        Connect();
        GetState();
        GetValue();
        UpdateProperties();
        UpdateNumber(new int[]{0,1,2});



        return true;
    }




    public String ProgressMsg(final int stackIndex, final int bracketIndex) {

        String stmsg="done ";
        int bn=BracketNum();
        if(numbers[2].value<2) {
            stmsg = stmsg + (bracketIndex + 1) + "/" +bn ;
            int rs=(bn-bracketIndex-1)*8;
            stmsg =stmsg +", remaining "+ToTime(rs);
        }
        else
        {
            stmsg = stmsg + (bracketIndex + 1) + "[" + (stackIndex + 1) + "]/" + bn + "[" + numbers[2].value + "]";
            int rs=((bn-bracketIndex)*numbers[2].value-stackIndex - 1)*numbers[1].value;
            stmsg = stmsg +", remaining "+ToTime(rs);
        }

        if (_cameraError != null) {
            for (String str : _cameraError)
                stmsg = stmsg + "\n" + str;
        }
        return stmsg;
    }


    public String [] TakePhotoBK(ArrayList<Integer> settingIdx, ArrayList<Integer> propertyIdx,
                                 ThetaSBKEventListener listener, int sleepms)
            throws JSONException, InterruptedException, IOException {

        int n=numbers[2].value;

        String []outNames=new String[n*(settingIdx.size()+1)];
        int []choices0={properties[0].choice,properties[1].choice,
                properties[2].choice,properties[3].choice};

        if(n<2) {
            outNames[0] = TakePhoto(sleepms);
            listener.onObjectChanged(0, 0);
        }
        else {
            String[] outs = TakePhotos(listener, 0, sleepms);
            System.arraycopy(outs, 0, outNames, 0, n);
        }

        for (int i = 0; i < settingIdx.size(); i++)
        {
            int pIndex=propertyIdx.get(i);
            properties[pIndex].choice = settingIdx.get(i);
            SetProperty(pIndex);
            listener.onPropertyChanged(pIndex);

            if(n<2) {
                outNames[1 + i] = TakePhoto(sleepms);
                listener.onObjectChanged(0,1+i);
            }
            else {
                String[] outs = TakePhotos(listener, 1+i, sleepms);
                System.arraycopy(outs, 0, outNames, (i+1)*n, n);
            }
        }

        for (int i = 0; i < 4; i++) {
            if(properties[i].choice != choices0[i])
            {
                properties[i].choice = choices0[i];
                SetProperty(i);
                listener.onPropertyChanged(i);
            }
        }
        return outNames;
    }

    public String [] TakePhotoBKWithDelay(ArrayList<Integer> settingIdx, ArrayList<Integer> propertyIdx,
                                 ThetaSBKEventListener listener, int sleepms)
            throws JSONException, InterruptedException, IOException {

        int n=numbers[2].value;

        String []outNames=new String[n*(settingIdx.size()+1)];
        int []choices0={properties[0].choice,properties[1].choice,
                properties[2].choice,properties[3].choice};

        if(n<2) {
            outNames[0] = TakePhotoWithDelay(listener,sleepms);
            listener.onObjectChanged(0, 0);
        }
        else {
            String[] outs = TakePhotosWithDelay(listener, 0, sleepms);
            System.arraycopy(outs, 0, outNames, 0, n);
        }

        if(settingIdx.isEmpty())
            return outNames;

        int delay=properties[12].choice;
        if(delay>0)
        {
            properties[12].choice=0;
            SetProperty(12);
        }

        for (int i = 0; i < settingIdx.size(); i++)
        {
            int pIndex=propertyIdx.get(i);
            properties[pIndex].choice = settingIdx.get(i);
            SetProperty(pIndex);
            listener.onPropertyChanged(pIndex);

            if(n<2) {
                outNames[1 + i] = TakePhoto(sleepms);
                listener.onObjectChanged(0,1+i);
            }
            else {
                String[] outs = TakePhotos(listener, 1+i, sleepms);
                System.arraycopy(outs, 0, outNames, (i+1)*n, n);
            }
        }

        if(delay>0)
        {
            properties[12].choice=delay;
            SetProperty(12);
        }

        for (int i = 0; i < 4; i++) {
            if(properties[i].choice != choices0[i])
            {
                properties[i].choice = choices0[i];
                SetProperty(i);
                listener.onPropertyChanged(i);
            }
        }
        return outNames;
    }



}
